package com.micro.service.gateway.web.rest;


import com.micro.service.account.share.dto.UserBaseDto;
import com.micro.service.account.share.service.UserBaseService;
import com.micro.service.common.dto.ResultDTO;
import com.micro.service.gateway.common.HeaderCommonInfo;
import com.micro.service.gateway.vo.UserTokenInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestOperations;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;

/**
 * @author lvxiucai
 * @description 请求头解析、用户信息获取
 * @date 2019/9/5
 */
@RestController
@Slf4j
public class BaseController {

    private RestOperations restTemplate = new RestTemplate();

    @Value("${security.oauth2.resource.token-info-uri}")
    private String checkTokenEndpointUrl;

    @Autowired
    private UserBaseService userBaseService;

    /**
     * @author lvxiucai
     * @description 从请求头里获取用户token信息
     * @date 2019/9/7
     * @return UserTokenInfo
     **/
    public UserTokenInfo getUserInfoFromToken(){
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String accessToken = request.getHeader("token");
        if(StringUtils.isEmpty(accessToken)){
            return null;
        }

        UserTokenInfo userTokenInfo = new UserTokenInfo();
        if(accessToken != null){
            MultiValueMap<String, String> formData = new LinkedMultiValueMap();
            formData.add("token", accessToken);
            HttpHeaders headers = new HttpHeaders();
            Map<String,Object> map = postForMap(checkTokenEndpointUrl,formData,headers);
            if(map != null && map.get("userId") != null){
                userTokenInfo.setAccessToken(accessToken);
                userTokenInfo.setUsername(map.get("user_name")!=null ? map.get("user_name").toString() : null);
                userTokenInfo.setUserType(map.get("userType")!=null ? Integer.parseInt(map.get("userType").toString()) : null);
                userTokenInfo.setMobile(map.get("mobile")!=null ? map.get("mobile").toString() : null);
                userTokenInfo.setAuthorities(map.get("authorities")!=null ? (List<String>) map.get("authorities") : null);
                userTokenInfo.setScope(map.get("scope")!=null ? (List<String>) map.get("scope") : null);
                userTokenInfo.setUserId(map.get("userId")!=null ? Long.parseLong(map.get("userId").toString()) : null);

                return userTokenInfo;
            }

            return null;
        }


        return userTokenInfo;
    }
    /**
     * @author lvxiucai
     * @description 根据token获取用户信息
     * @date 2020/4/13
     * @return
     **/
    private Map<String, Object> postForMap(String path, MultiValueMap<String, String> formData, HttpHeaders headers) {
        if(StringUtils.isEmpty(path)){
            return null;
        }
        Map map = (Map)this.restTemplate.exchange(path, HttpMethod.POST, new HttpEntity(formData, headers), Map.class, new Object[0]).getBody();
        return map;
    }

    /**
     * @author lvxiucai
     * @description 获取用户头像等基础信息
     * @date 2019/9/7
     * @param userId
     * @return UserBaseDto
     **/
    public UserBaseDto getUserBaseInfo(Long userId){
        if(userId == null){
            return null;
        }

        return userBaseService.selectById(userId);
    }



    /**
     * @author lvxiucai
     * @description 从请求头中获取信息
     * @date 2019/9/23
     * @return HeaderCommonInfo
     **/
        public HeaderCommonInfo getHeaderCommonInfo(){
        HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
        HeaderCommonInfo headerInfo = new HeaderCommonInfo();
        Enumeration headerNames = request.getHeaderNames();
        while (headerNames.hasMoreElements()){
            String key = (String) headerNames.nextElement();
            String value = request.getHeader(key);
            switch (key){
                case "sourceType":
                    if(value != null){
                        headerInfo.setSourceType(value);
                    };break;
                case "imei":
                    if(value != null){
                        headerInfo.setImei(value);
                    };break;
                case "longitude":
                    if(value != null){
                        headerInfo.setLongitude(value);
                    };break;
                case "latitude":
                    if(value != null){
                        headerInfo.setLatitude(value);
                    };break;
                case "province":
                    if(value != null){
                        headerInfo.setProvince(value);
                    };break;
                case "city":
                    if(value != null){
                        headerInfo.setCity(value);
                    };break;
                case "community":
                    if(value != null){
                        headerInfo.setCommunity(value);
                    };break;
                case "district":
                    if(value != null){
                        headerInfo.setCommunity(value);
                    };break;
                case "street":
                    if(value != null){
                        headerInfo.setStreet(value);
                    };break;
                case "streetNum":
                    if(value != null){
                        headerInfo.setStreetNum(value);
                    };break;
                case "version":
                    if(value != null){
                        headerInfo.setVersion(value);
                    };break;
                case "machinetype":
                    if(value != null){
                        headerInfo.setMachineType(value);
                    };break;
                case "token":
                    if(value != null){
                        headerInfo.setToken(value);
                    };break;
                default:
            }
        }
        return headerInfo;
    }

}
